package nc.bs.gl.report.impl;

import java.sql.Types;
import java.util.*;

import com.ufida.report.anareport.base.BaseSearchTemplateCondition;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.gl.report.itf.SupplierBalanceReportService;
import nc.bs.gl.util.RePortUtil;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.pub.smart.context.SmartContext;
import nc.pub.smart.data.DataSet;
import nc.pub.smart.metadata.DataTypeConstant;
import nc.pub.smart.metadata.Field;
import nc.pub.smart.metadata.MetaData;
import nc.vo.am.common.util.CollectionUtils;
import nc.vo.pub.BusinessException;
import nccloud.dto.baseapp.querytree.dataformat.Condition;
import nccloud.dto.baseapp.querytree.dataformat.QueryTreeFormatVO;
import nccloud.pubimpl.gl.assbalance.AssBalanceQueryBO;
import nccloud.pubitf.gl.account.IAccountReportWebService;

public class SupplierBalanceReportServiceImpl implements SupplierBalanceReportService {

	String[] fields = new String[] { "nyear","nyearpk", "nmonth","nmonthpk", "pk", "code", "name" ,
			"qcye", "bqjf", "bqdf","jflj","dflj","qmye","fx","pk_group"};
	// 7 期初余额,8 本期借方,9 贷方累计,
	// 10 借方累计,11 贷方累计,12期末余额
	String[] fieldCaptions = new String[] { "年度", "年度pk", "月份", "月份pk", "供应商主键", "供应商编码", "供应商名称", "期初余额", "本期借方", "本期贷方",
			"借方累计","贷方累计", "期末余额","借贷方向","集团PK" };
	String nyear = ""; // 年度
	String nmonth = ""; // 月份
	@Override
	public DataSet supplierBalanceDataProcess(SmartContext context) throws BusinessException {
		// 初始化元数据
		MetaData metadata = this.initMetaData();

		// 获取查询条件
		handelContext(context);

		String pk = ""; // 客户编码做成参照，实际查主键
		if (null != context.getAttribute("pk")) {
			pk = (String) context.getAttribute("pk");
		}
		String nyear = ""; // 年度
		String nyearpk = ""; // 年度主键
		if (null != context.getAttribute("nyearpk")) {
			nyearpk = (String) context.getAttribute("nyearpk");
			nyear = getYear(nyearpk);
		}
		String nmonth = ""; // 月份
		String nmonthpk = ""; // 月份主键
		if (null != context.getAttribute("nmonthpk")) {
			nmonthpk = (String) context.getAttribute("nmonthpk");
			nmonth = getMonth(nmonthpk);
		}
		if("".equals(nmonth) || "".equals(nyear)){
			return new DataSet(metadata, null);
		}
		Collection<Object[]> result = new ArrayList<Object[]>();
		List<String> pk_suppliers = new ArrayList<>();
		String fzxnName = "供应商档案";
		String pk_fzmx = "1001Z01000000000HQWC";
		if(!"".equals(pk)){ // 指定项目查询
			String[] pks = pk.split(",");
			pk_suppliers =  Arrays.stream(pks).toList();
		}else{
			pk_suppliers = this.getPk_Suppliers(fzxnName, pk_fzmx,  nyear, nmonth);
		}
		if (pk_suppliers.isEmpty()) return new DataSet(metadata, null);
		for (String pk_supplier : pk_suppliers) {
			if(pk_supplier == null) continue;
			Map<String, Object> xmMap = RePortUtil.buildFZMXMap(fzxnName, pk_fzmx, nyear, nmonth, pk_supplier);
//			Map<String, Object> res = new AssBalanceQueryBO().queryAssBalance(xmMap);
			IAccountReportWebService lookup = NCLocator.getInstance().lookup(IAccountReportWebService.class);
			Map<String, Object> res = lookup.queryAssBalance(xmMap);
			Object[] objects = RePortUtil.FXMXHandlerResult(res, nyear, nyearpk, nmonth, nmonthpk);
			if(objects != null){
				result.add(objects);
			}
		}
		if (result.isEmpty()) return new DataSet(metadata, null);
		// 查询客户余额相关数据
		Object[][] dataarr = result.toArray(new Object[result.size() == 0 ? 1 : result.size()][]);
		// 处理数据
		return new DataSet(metadata, dataarr);
	}

	/**
	 * 获取需要查询档案PK
	 * @param nyear
	 * @param nmonth
	 * @return
	 */
	public List<String> getPk_Suppliers(String fzxnName,String pk_fzmx, String nyear,String nmonth) throws BusinessException {
		StringBuilder sql = new StringBuilder();
		sql.append(" SELECT\n" );
		sql.append("\tdistinct pk_supplier\n" );
		sql.append("FROM\n" );
		sql.append("\tbd_supplier \n" );
		sql.append("WHERE\n" );
		sql.append("\t1 = 1 \n" );
		sql.append("\tAND ( ( ( pk_org = '0001A210000000000JB9' ) ) ) \n" );
		sql.append("\tAND ( enablestate IN ( 2 ) ) ");

		List<String> pks = (List<String>)this.getBaseDAO().executeQuery(sql.toString(), new ColumnListProcessor());
		if (pks.isEmpty()) {
			return new ArrayList<>();
		}
		return RePortUtil.getAllPks(pks,fzxnName,pk_fzmx,nyear,nmonth);
	}

	/**
	 * 	初始化metadata
	 * @return
	 */
	private MetaData initMetaData() {
		Field[] FieldInfo = initField();
		MetaData md = new MetaData();
		for (int i = 0; i < fields.length; i++) {
			Field field = FieldInfo[i];
			md.addField(field);
		}
		return md;
	}

	/**
	 * 	初始化返回字段
	 * @return
	 */
	private Field[] initField() {
		Field[] FieldInfo = new Field[fields.length];
		for (int i = 0; i < fields.length; i++) {
			Field filed = new Field();
			filed.setCaption(fieldCaptions[i]);
			filed.setDbColumnType(Types.VARCHAR);
			if ( i == 7 || i == 8 || i == 9 || i == 10 || i == 11 || i == 12) { // 金额 字段类型，根据情况定
				filed.setDbColumnType(Types.DOUBLE);
				filed.setPrecision(28);
				filed.setScale(2);
			}else if (i == 6) { // 项目字段特殊处理设置字段长度
				filed.setDataType(DataTypeConstant.STRING);
				filed.setDbColumnType(Types.VARCHAR);
				filed.setPrecision(4000);
			}
			filed.setFldname(fields[i]);
			FieldInfo[i] = filed;
		}
		return FieldInfo;
	}

	public void handelContext(SmartContext context) {
		BaseSearchTemplateCondition templateCondition = (BaseSearchTemplateCondition)context.getAttribute("FreeReport_All_Condition");
		if(null != templateCondition) {
			QueryTreeFormatVO conditionTree = templateCondition.getConditionTree();
			List<Condition> list = conditionTree.getQuerycondition().getConditions();
			for(Condition cond : list) {
				String file = cond.getField();
				String val = cond.getValue().getFirstvalue();
				if("between".equals(cond.getOprtype())) {
					val = cond.getValue().getFirstvalue()+","+cond.getValue().getSecondvalue();
				}
				context.setAttribute(file, val);
			}
		}
	}

	/**
	 * 	根据主键查询年度
	 * @param nyearpk  年度
	 * @return
	 * @throws BusinessException
	 */
	public String getYear(String nyearpk) throws BusinessException {

		StringBuffer sql = new StringBuffer();
		sql.append("SELECT periodyear FROM  bd_accperiod  WHERE 1 = 1 \n");
		if (!"".equals(nyearpk)) {
			sql.append("   AND pk_accperiod = '" + nyearpk + "' \n");// 年度主键
		}

		List<Map<String, Object>> sqlResult = (List<Map<String, Object>>) this.getBaseDAO().executeQuery(sql.toString(),
				new MapListProcessor());
		if (CollectionUtils.isEmpty(sqlResult)) {
			return null;
		}

		return (String) sqlResult.get(0).get("periodyear");
	}

	/**
	 * 	根据主键查询月份
	 * @param nmonthpk         月份
	 * @return
	 * @throws BusinessException
	 */
	public String getMonth(String nmonthpk) throws BusinessException {

		StringBuffer sql = new StringBuffer();
		sql.append("SELECT accperiodmth FROM  bd_accperiodmonth  WHERE 1 = 1 \n");
		if (!"".equals(nmonthpk)) {
			sql.append("   AND pk_accperiodmonth = '" + nmonthpk + "' \n");// 年度主键
		}

		List<Map<String, Object>> sqlResult = (List<Map<String, Object>>) this.getBaseDAO().executeQuery(sql.toString(),
				new MapListProcessor());
		if (CollectionUtils.isEmpty(sqlResult)) {
			return null;
		}

		return (String) sqlResult.get(0).get("accperiodmth");
	}

	private BaseDAO baseDAO;

	public BaseDAO getBaseDAO() {
		return baseDAO == null ? new BaseDAO() : baseDAO;
	}

}
